<template>
  <div
    class="pic-zoom"
    :style="imageStyle"
    @mouseenter="mouseInHandler"
    @mousemove="mouseInHandler">
    <!-- 缩略图 -->
    <img :src="url" :alt="url">
    <!-- 放大图 -->
    <div class="big-image" :style="bigImageStyle">
      <img :src="bigUrl" :alt="bigUrl" :style="{
        left: `-${scale * mouse.left}px`,
        top: `-${scale * mouse.top}px`,
        width: `${scale * 100}%`,
        height: `${scale * 100}%`
      }">
    </div>
    <!-- 鼠标位置 -->
    <div class="mouse-area" :style="{
      width: `${100 / scale}%`,
      height: `${100 / scale}%`,
      left: `${mouse.left}px`,
      top: `${mouse.top}px`
    }"></div>
  </div>
</template>

<script>
import _ from 'lodash'

export default {
  props: {
    // 缩略图的大小
    url: {
      type: String,
      default: ''
    },
    // 放大图的大小
    bigUrl: {
      type: String,
      default: ''
    },
    // 缩略图的宽度
    width: {
      type: String,
      default: ''
    },
    // 缩略图的高度
    height: {
      type: String,
      default: ''
    },
    // 缩略图和放大图的放大比例
    scale: {
      type: Number,
      default: 2
    },
    // 放大图和缩略图之间的偏移
    translate: {
      type: String,
      default: '10px'
    }
  },

  computed: {
    /**
     * 外部设置的样式
     */
    imageStyle () {
      // 最后返回的样式
      let styleStr = ''
      // 如果设置了宽度
      if (this.width) {
        styleStr += `width: ${this.width};`
      }
      // 如果设置了宽度
      if (this.height) {
        styleStr += `height: ${this.height};`
      }
      return styleStr
    },

    /**
     * 放大图的样式
     */
    bigImageStyle () {
      let styleStr = ''
      // 如果放大图需要偏移
      if (this.translate) {
        styleStr += `left: calc(100% + ${this.translate});`
      }
      return styleStr
    }
  },

  data () {
    return {
      // 鼠标位置
      mouse: {
        left: 0,
        top: 0
      },
      // 当前组件的偏移量
      parentLocation: {
        left: 0,
        top: 0
      }
    }
  },

  created () {
    this.$nextTick(() => {
      // 获取当前dom对象
      const picZoom = document.querySelector('.pic-zoom')
      // 记住当前组件的左右偏移
      this.parentLocation = {
        left: picZoom.offsetParent.offsetLeft,
        top: picZoom.offsetParent.offsetTop
      }
    })
  },

  methods: {
    /**
     * 鼠标移动事件
     * @params { Object } event 当前鼠标事件
     */
    mouseInHandler: _.throttle(function (event) {
      // 鼠标位置
      this.mouse = {
        ...this.move(event)
      }
    }, 6),

    /**
     * 移动方法，返回距离左边和上边的距离
     * @param  { Object } event 事件
     */
    move ({ pageX, pageY }) {
      // 容器宽度
      const CONTAINER_WIDTH = parseInt(this.width)
      // 鼠标移动区域的宽度
      const WIDTH = CONTAINER_WIDTH / this.scale
      const HARF_WIDTH = WIDTH / 2
      // 获取当前组件上下左右边距
      const { left, top } = this.parentLocation
      // 最后的偏移量
      const offset = { left: 0, top: 0 }
      // 如果当前在左边界右边
      if (pageX - HARF_WIDTH > left) {
        // 如果当前在右边界左边
        if (pageX < left + CONTAINER_WIDTH - HARF_WIDTH) {
          offset.left = pageX - left - HARF_WIDTH
        } else {
          offset.left = CONTAINER_WIDTH - WIDTH
        }
      }
      // 如果当前在上边界下面
      if (pageY - HARF_WIDTH > top) {
        if (pageY < top + CONTAINER_WIDTH - HARF_WIDTH) {
          offset.top = pageY - top - HARF_WIDTH
        } else {
          offset.top = CONTAINER_WIDTH - WIDTH
        }
      }
      return offset
    }
  }
}
</script>

<style lang="less" scoped>
.pic-zoom {
  border: 1px solid #e8e8e8;
  width: 100%;
  height: 100%;
  position: relative;
  img {
    background: #f4f4f4;
    width: 100%;
    height: 100%;
  }
  .big-image {
    background: #ffffff;
    border: 1px solid #e8e8e8;
    display: none;
    width: 100%;
    height: 100%;
    position: absolute;
    overflow: hidden;
    top: -1px;
    z-index: 9;
    img {
      width: 200%;
      height: 200%;
      position: absolute;
    }
  }
  .mouse-area {
    background: rgba(0, 0, 0, 0.2);
    display: none;
    position: absolute;
  }
  &:hover {
    .big-image, .mouse-area {
      display: block;
    }
  }
}
</style>
